//
//  LBDownloaderBlockOperation.m
//  LBDownloader
//
//  Created by WuShiHai on 19/6/14.
//  Copyright (c) 2019 Lebbay All rights reserved.
//

#import "LBDownloaderBlockOperation.h"
#import "LBDownloader.h"
#import <SSZipArchive/ZipArchive.h>
#import "LBDownloaderFolderUtil.h"

@interface LBDownloaderBlockOperation ()

@property (assign, nonatomic, getter = isExecuting) BOOL executing;
@property (assign, nonatomic, getter = isFinished) BOOL finished;

@property (nonatomic, copy) NSData *resumeData;
@property (nonatomic, strong) NSURLSessionDownloadTask *task;

@property (nonatomic, assign, readwrite) BOOL isSuccess;

@end

@implementation LBDownloaderBlockOperation

@synthesize executing = _executing;
@synthesize finished = _finished;

- (instancetype)init{
    self = [super init];
    if (self){
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appDidEnterForeground:) name:UIApplicationWillEnterForegroundNotification object:nil];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appWillEnterBackground:) name:UIApplicationDidEnterBackgroundNotification object:nil];
        
    }
    return self;
}

#pragma mark - Core
- (void)start {
    if (self.isFinished) {
        return;
    }
    //默认成功
    self.isSuccess = YES;
    self.executing = YES;
    
    //操作目录不存在就创建
    if ([LBDownloaderFolderUtil inspectFolderPath:[self.work.downloader.filePath stringByDeletingLastPathComponent]]) {
        if (self.work.downloader.isUnzip == NO) {
            //判断本地是否有完成的下载
            if ([self.work isDownloaded]) {
                self.isSuccess = YES;
                self.finished = YES;
            } else {
                if (self.cacheOnly) {
                    //本地没有该缓存 认为操作失败
                    self.isSuccess = NO;
                    self.finished = YES;
                } else {
                    [self download];
                }
            }
        } else {
            if ([self.work isUnziped]) {
                self.isSuccess = YES;
                self.finished = YES;
            } else {
                //判断本地是否有完成的下载
                if ([self.work isDownloaded]) {
                    [self unzip];
                } else {
                    if (self.cacheOnly) {
                        //本地没有该缓存 认为操作失败
                        self.isSuccess = NO;
                        self.finished = YES;
                    } else {
                        [self download];
                    }
                }
            }
        }
    } else {
        self.isSuccess = NO;
        self.finished = YES;
    }
}

- (void)download{
    
    if (self.url.length == 0 || self.url.length == 0){
        self.finished = YES;
        return;
    }
    
    self.work.state = LBDownloaderFileStateDownloading;
    
    __weak typeof(self) weakSelf = self;
    
    NSURL *(^destinationBlock)(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) = ^(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response){
        NSURL *destURL = nil;
        if (weakSelf.work.downloader.filePath) {
            return [NSURL fileURLWithPath:weakSelf.work.downloader.filePath];
        }
        return destURL;
    };
    
    void (^completeBlock)(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) = ^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error){
        if (!error){
            weakSelf.work.state = LBDownloaderFileStateDownloaded;
            if (weakSelf.work.downloader.isUnzip) {
                [weakSelf unzip];
            } else {
                weakSelf.isSuccess = YES;
                weakSelf.finished = YES;
            }
        } else{
            weakSelf.work.state = LBDownloaderFileStateDownloadFailed;
            weakSelf.isSuccess = NO;
            weakSelf.finished = YES;
        }
    };
    
    AFURLSessionManager *sessionManager = [LBDownloader manager].sessionManager;
    if (self.resumeData){
        NSURLSessionDownloadTask *task = [sessionManager downloadTaskWithResumeData:self.resumeData progress:self.downloadProgress destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
            NSURL *destURL = destinationBlock(targetPath,response);
            return destURL;
        } completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
            completeBlock(response,filePath,error);
        }];
        self.task = task;
        [task resume];
    } else{
        NSURLRequest *urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:self.url] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60 * 3];
        
        NSURLSessionDownloadTask *task = [sessionManager downloadTaskWithRequest:urlRequest progress:self.downloadProgress destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
            NSURL *destURL = destinationBlock(targetPath,response);
            return destURL;
        } completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
            completeBlock(response,filePath,error);
        }];
        self.task = task;
        [task resume];
    }
    
}

- (void)unzip {
    
    self.work.state = LBDownloaderFileStateUnziping;
    
//    BOOL success = [SSZipArchive unzipFileAtPath:self.work.downloader.filePath
//                                   toDestination:self.work.downloader.unzipFolderPath];
    
    NSError *error = nil;
    [SSZipArchive unzipFileAtPath:self.work.downloader.filePath
                    toDestination:self.work.downloader.unzipFolderPath
               preserveAttributes:YES
                        overwrite:YES
                         password:nil
                            error:&error
                         delegate:nil];
    if (!error){
        self.work.state = LBDownloaderFileStateUnziped;
        self.isSuccess = [self saveUnzipedState];
        //删除zip文件
        //测试期间先不删
        //        NSError *error = nil;
        //        [[NSFileManager defaultManager] removeItemAtPath:self.work.downloader.filePath
        //                                                   error:&error];
        //        if (error){
        //            NSLog(@" 解压文件删除失败 %@",error);
        //        }
    } else{
        self.work.state = LBDownloaderFileStateUnzipFailed;
        self.isSuccess = NO;
    }
    self.finished = YES;
}

- (BOOL)saveUnzipedState{
    NSFileManager *fileManager = [NSFileManager defaultManager];
    BOOL success = [fileManager createFileAtPath:self.work.downloader.unzipStateFilePath
                                        contents:nil
                                      attributes:nil];
    if (!success) {
        
    } else {
#if DEBUG
        [fileManager createFileAtPath:self.work.downloader.debugInfoFilePath
                             contents:[self.work.downloader.url dataUsingEncoding:NSUTF8StringEncoding]
                           attributes:nil];
#endif
    }
    return success;
}

#pragma mark - Setter
- (void)setFinished:(BOOL)finished {
    [self willChangeValueForKey:@"isFinished"];
    _finished = finished;
    if (_finished && [_delegate respondsToSelector:@selector(didOperationCompleteTask:)]) {
        [_delegate didOperationCompleteTask:self];
    }
    [self didChangeValueForKey:@"isFinished"];
}
- (void)setExecuting:(BOOL)executing {
    [self willChangeValueForKey:@"isExecuting"];
    _executing = executing;
    [self didChangeValueForKey:@"isExecuting"];
}


#pragma mark - Getter
- (NSString *)url {
    return self.work.downloader.url;
}
- (LBDownloaderFileState)state {
    return self.work.state;
}
- (BOOL)isAsynchronous {
    return YES;
}
#pragma mark - NSNotification
- (void)appDidEnterForeground:(NSNotification *)noti{
    NSLog(@"恢复下载任务: %@",self.work.downloader.url);
    //继续下载
    [self start];
}

- (void)appWillEnterBackground:(NSNotification *)noti{
    NSLog(@"取消下载任务: %@",self.work.downloader.url);
    __weak __typeof(&*self) weakSelf = self;
    [self.task cancelByProducingResumeData:^(NSData * _Nullable resumeData) {
        weakSelf.resumeData = resumeData;
    }];
}

- (void)dealloc{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

@end
